
package domain;

import java.rmi.RemoteException ;
import java.rmi.server.UnicastRemoteObject ;
import java.util.Date ;
import java.util.Set ;
import java.util.Vector ;

import presentation.UIDirectory ;
import presentation.UIMember ;
import presentation.UIPost ;
import presentation.UIThread ;
import presentation.UIUser ;
import util.DuplicationException ;
import util.NotFoundException ;
import util.Statistics ;
import domain.message.MessageController ;
import domain.searchEngine.SearchEngine ;
import domain.searchEngine.SearchEngineFactory ;
import domain.searchEngine.SearchResult ;
import domain.user.BadPasswordException ;
import domain.user.UnpermittedActionException ;
import domain.user.UserController ;

/**
 * facade over all the controllers of the domain layer.
 */
public class LocalForum extends UnicastRemoteObject implements ForumLogic
{

	private static final long serialVersionUID = 2172592148504228571L ;

	/** search controller **/
	private final SearchEngine searchEngine;

	/** message controller **/
	private final MessageController messageController;

	/** user controller **/
	private final UserController userController;

	/**
	 * @param data all data of this forum.
	 * @param searchProvider object which provides search components to this forum.
	 * @throws RemoteException if the forum cannot be published.
	 */
	public LocalForum(final ForumData data, final SearchEngineFactory searchProvider) throws RemoteException
	{
		super() ;
		this.messageController = new MessageController(data, searchProvider.getIndexAgent());
		this.userController = new UserController(data, searchProvider.getIndexAgent());
		this.searchEngine = searchProvider.getSearchEngine() ;
	}

	/**
	 * @see domain.ForumLogic#addAdministratorPrivileges(long, java.lang.String)
	 */
	public void addAdministratorPrivileges(final long adminId, final String userName)
		throws NotFoundException, UnpermittedActionException
	{
		this.userController.addAdministratorPrivileges(adminId, userName);
	}


	/**
	 * @see domain.ForumLogic#addDirectory(long, long, java.lang.String)
	 */
	public UIDirectory addDirectory(final long userId, final long containerDirectoryId, final String newDirName) throws UnpermittedActionException, NotFoundException
	{
		return this.messageController.addDirectory(userId, containerDirectoryId, newDirName);
	}


	/**
	 * @see domain.ForumLogic#addModeratorPrivileges(long, java.lang.String)
	 */
	public void addModeratorPrivileges(final long adminId, final String userName)
		throws NotFoundException, UnpermittedActionException
	{
		this.userController.addModeratorPrivileges(adminId, userName);
	}

	/**
	 * @see domain.ForumLogic#addPost(long, long, java.lang.String)
	 */
	public UIPost addPost(final long threadId, final long userId, final String msg)
		throws UnpermittedActionException, NotFoundException
	{
		return this.messageController.addPost(threadId, userId, msg);
	}

	/**
	 * @see domain.ForumLogic#addThread(long, long, java.lang.String, java.lang.String)
	 */
	public UIThread addThread(final long dirId, final long userId, final String subject, final String msg)
		throws UnpermittedActionException, NotFoundException
	{
		return this.messageController.addThread(dirId, userId, subject, msg);
	}

	/**
	 * @see domain.ForumLogic#deletePost(long, long, long)
	 */
	public void deletePost(final long userId, final long postId, final long threadId) throws UnpermittedActionException, NotFoundException
	{
		this.messageController.deletePost(userId, postId, threadId);
	}

	/**
	 * @see domain.ForumLogic#deleteThread(long, long, long)
	 */
	public void deleteThread(final long userId, final long dirId, final long threadId) throws UnpermittedActionException, NotFoundException
	{
		this.messageController.deleteThread(userId, dirId, threadId);
	}

	/**
	 * @see domain.ForumLogic#editPost(long, long, java.lang.String)
	 */
	public void editPost(final long postId, final long userId, final String msg)
		throws UnpermittedActionException, NotFoundException
	{
		this.messageController.editPost(postId, userId, msg);
	}

	/**
	 * @see domain.ForumLogic#editThreadTopic(long, long, java.lang.String)
	 */
	public void editThreadTopic(final long threadId, final long userId, final String topic)
		throws UnpermittedActionException, NotFoundException
	{
		this.messageController.editThreadTopic(threadId, userId, topic);
	}

	/**
	 * exit the system - shutting down the forum
	 */
	public void exit()
	{
		this.messageController.exit();
		this.userController.exit();
		this.searchEngine.close() ;
	}

	/**
	 * @see domain.ForumLogic#exitUser(long)
	 */
	public void exitUser(final long userId)
	{
		this.userController.exitUser(userId);
	}

	/**
	 * @see domain.ForumLogic#getActiveGuests()
	 */
	public int getActiveGuests(){
		return this.userController.getActiveGuestCount();
	}

	/**
	 * @return domain.ForumLogic#getActiveMemberNames()
	 */
	public Set<String> getActiveMemberNames(){
		return this.userController.getActiveMemberNames();
	}

	/**
	 * @see domain.ForumLogic#getDirectory(long)
	 */
	@Override
	public UIDirectory getDirectory(final long id) throws NotFoundException
	{
		return this.messageController.getDirectory(id) ;
	}

	/**
	 * @see domain.ForumLogic#getMember(long)
	 */
	@Override
	public UIMember getMember(final long id) throws NotFoundException
	{
		return this.userController.getMemberById(id);
	}

	/**
	 * @see domain.ForumLogic#getMemberById(long)
	 */
	public UIMember getMemberById(final long userId) throws NotFoundException
	{
		return this.userController.getMemberById(userId);
	}

	/**
	 * @see domain.ForumLogic#getMemberId(java.lang.String)
	 */
	public long getMemberId(final String username) throws NotFoundException
	{
		return this.userController.getMemberId(username);
	}

	/**
	 * @see domain.ForumLogic#getPost(long)
	 */
	@Override
	public UIPost getPost(final long id) throws NotFoundException
	{
		return this.messageController.viewPost(id) ;
	}

	/**
	 * @see domain.ForumLogic#getPosts(long)
	 */
	public Vector<UIPost> getPosts(final long threadId) throws NotFoundException
	{
		return this.messageController.getPosts(threadId);
	}

	/**
	 * @see domain.ForumLogic#getPostStatistics()
	 */
	public Statistics getPostStatistics()
	{
		return this.searchEngine.getPostStatistics() ;
	}

	/**
	 * @see domain.ForumLogic#getPostStatisticsForMember(long)
	 */
	public Statistics getPostStatisticsForMember(final long id)
	{
		return this.searchEngine.getPostStatisticsForMember(id) ;
	}

	/**
	 * @see domain.ForumLogic#getRootDirectory()
	 */
	public UIDirectory getRootDirectory()
	{
		return this.messageController.getRootDirectory();
	}

	/**
	 * @see domain.ForumLogic#getSubDirectories(long)
	 */
	public Vector<UIDirectory> getSubDirectories(final long dirId) throws NotFoundException
	{
		return this.messageController.getSubDirectories(dirId);
	}

	/**
	 * @see domain.ForumLogic#getThread(long)
	 */
	@Override
	public UIThread getThread(final long id) throws NotFoundException
	{
		return this.messageController.getThread(id) ;
	}

	/**
	 * @see domain.ForumLogic#getThreads(long)
	 */
	public Vector<UIThread> getThreads(final long dirId) throws NotFoundException
	{
		return this.messageController.getThreads(dirId) ;
	}

	/**
	 * @see domain.ForumLogic#getUserStatistics()
	 */
	@Override
	public Statistics getUserStatistics()
	{
		return this.searchEngine.getUserStatistics() ;
	}

	/**
	 * @see domain.ForumLogic#login(java.lang.String, java.lang.String)
	 */
	public UIUser login(final String name, final String password) throws NotFoundException,
		BadPasswordException
	{
		return this.userController.login(name, password);
	}

	/**
	 * @see domain.ForumLogic#logout(long)
	 */
	public void logout(final long userId) throws NotFoundException, UnpermittedActionException
	{
		this.userController.logout(userId);
	}

	/**
	 * TODO
	 * @see domain.ForumLogic#putLogin(java.lang.String, java.util.Date)
	 */
	@Override
	public void putLogin(final String username, final Date time)
	{
		this.userController.putLogin(username, time) ;
	}

	/**
	 * TODO
	 * @see domain.ForumLogic#putPost(java.lang.String, java.util.Date)
	 */
	@Override
	public void putPost(final String username, final Date time)
	{
		this.messageController.putPost(username, time) ;
	}

	/**
	 * @see domain.ForumLogic#register(java.lang.String, java.lang.String)
	 */
	public void register(final String name, final String password) throws DuplicationException
	{
		this.userController.register(name, password);
	}

	/**
	 * @see domain.ForumLogic#register(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public void register(final String username, final String password, final String firstName, final String lastName,
		final String dob, final String chosenGender, final String residence)
		throws DuplicationException
	{
		this.userController.register(username, password,firstName,lastName,dob,
			chosenGender,residence);

	}

	/**
	 * @see domain.ForumLogic#registerGuest()
	 */
	public UIUser registerGuest()
	{
		return this.userController.registerGuest();
	}

	/**
	 * @see domain.ForumLogic#searchByAuthor(java.lang.String)
	 */
	public Set<SearchResult> searchByAuthor(final String authorName)
	{
		 return this.searchEngine.searchByAuthor(authorName);
	}

	/**
	 * @see domain.ForumLogic#searchByContent(java.lang.String)
	 */
	public Set<SearchResult> searchByContent(final String message)
	{
		return this.searchEngine.searchByContent(message);
	}

	/**
	 * @see domain.ForumLogic#searchByDate(java.util.Date, java.util.Date)
	 */
	public Set<SearchResult> searchByDate(final Date fromDate, final Date toDate)
	{
		return  this.searchEngine.searchByDate(fromDate, toDate);
	}

	/**
	 * @see domain.ForumLogic#unregisterGuest(long)
	 */
	public void unregisterGuest(final long userId)
	{
		this.userController.unregisterGuest(userId);
	}

	/**
	 * @see domain.ForumLogic#updateMemberDetails(long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public void updateMemberDetails(final long userId,final String newFirstName, final String newLastName, final String dob, final String chosenGender,
		final String newResidence) throws NotFoundException, UnpermittedActionException
	{
		this.userController.updateMemberDetails(userId,newFirstName, newLastName, dob, chosenGender,
			newResidence);

	}

	/**
	 * @see domain.ForumLogic#updatePassword(long, java.lang.String, java.lang.String)
	 */
	@Override
	public void updatePassword(final long userId, final String oldPassword, final String newPassword)
	throws NotFoundException, BadPasswordException
	{
		this.userController.updatePassword(userId,oldPassword,newPassword);

	}

	/**
	 * @see domain.ForumLogic#viewPost(long)
	 */
	public UIPost viewPost(final long postId) throws NotFoundException
	{
		return this.messageController.viewPost(postId);
	}

	
	/** 
	 * @see domain.ForumLogic#addPost(long, long, java.lang.String, java.util.Date)
	 */
	@Override
	public UIPost addPost(long threadId, long userId, String msg, Date time)
		throws UnpermittedActionException, NotFoundException
	{
		return this.messageController.addPost(threadId, userId, msg, time);
	}
}
